/*
 *  Copyright (C) 2010 Francesco Boffa (aka AlfaOmega08)
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package Engine;

import ImageFormats.*;

public class Executable {

	public long Pc;
	public long Gp;
	public long Sp;
	public long TextOffset;
	public long DataOffset;
	public long TextPointer;
	public long TextSize;
	public long DataPointer;
	public long DataSize;
	public long BssPointer;
	public long BssSize;
	public long StackPointer;
	public long StackSize;
	public byte[] Exe;

	public Executable(ImageFormat Image, String Path) throws Exception {
		TreeElement ExecInfo = Image.getNodeInfo(Path);
		Exe = Image.getFileContent(ExecInfo);

		String Sign = new String(Exe, 0, 8);
		System.out.println("Signature: " + Sign);
		if (!Sign.equals(new String("PS-X EXE"))) {
			throw new Exception("The file is not a PS-X EXEcutable");
		}

		TextOffset = getLong(8);
		DataOffset = getLong(12);
		Pc = getLong(16);
		Gp = getLong(20);
		TextPointer = getLong(24);
		TextSize = getLong(28);
		DataPointer = getLong(32);
		DataSize = getLong(36);
		BssPointer = getLong(40);
		BssSize = getLong(44);
		StackPointer = getLong(48);
		StackSize = getLong(52);
	}

	private long getLong(int offset) {
		long res = (long) (Exe[offset] & 0xFF);
		res |= (long) ((Exe[offset + 1] & 0xFF) << 8);
		res |= (long) ((Exe[offset + 2] & 0xFF) << 16);
		res |= (long) ((Exe[offset + 3] & 0xFF) << 24);

		return res;
	}

	public void Load(Memory mem) throws Exception {
		int offset = 2048;
		int endOffset = offset + (int) TextSize;

		for (; offset < endOffset; offset++)
			mem.Write((int) TextPointer + offset - 2048, Exe[offset], 1);
	}
}

